<template>
  <div class="menu-management-container">
    <div class="header">
      <el-button type="primary" @click="handleAddRoot">添加根菜单</el-button>
    </div>

    <el-table
      :data="processedMenuData"
      row-key="path"
      :tree-props="{ children: 'children' }"
      border
      stripe
      style="width: 100%; margin-top: 20px"
    >
      <el-table-column prop="meta.title" label="菜单名称" width="220" />
      <el-table-column prop="path" label="路由路径" width="220" />
      <el-table-column label="图标" width="120">
        <template #default="{ row }">
          <el-icon v-if="row.meta.icon">
            <component :is="row.meta.icon" />
          </el-icon>
          <span v-else>—</span>
        </template>
      </el-table-column>
      <el-table-column label="组件路径">
        <template #default="{ row }">{{ row.component || '—' }}</template>
      </el-table-column>
      <el-table-column label="按钮权限" width="180">
        <template #default="{ row }">
          <el-tag
            v-for="perm in row.meta.butPermission"
            :key="perm"
            size="small"
            class="perm-tag"
          >
            {{ perm }}
          </el-tag>
          <span v-if="!row.meta.butPermission?.length">—</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="240" fixed="right">
        <template #default="{ row }">
          <el-button size="small" @click="handleAddChild(row)">添加子项</el-button>
          <el-button size="small" type="primary" @click="handleEdit(row)">编辑</el-button>
          <el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="600px"
      :close-on-click-modal="false"
    >
      <el-form
        ref="formRef"
        :model="currentMenu"
        :rules="formRules"
        label-width="100px"
        label-position="right"
      >
        <el-form-item label="菜单名称" prop="meta.title">
          <el-input v-model="currentMenu.meta.title" placeholder="请输入菜单名称" />
        </el-form-item>
        <el-form-item label="路由路径" prop="path">
          <el-input v-model="currentMenu.path" placeholder="请输入路由路径" />
        </el-form-item>
        <el-form-item label="组件路径">
          <el-input v-model="currentMenu.component" placeholder="请输入组件路径" />
        </el-form-item>
        <el-form-item label="选择图标">
          <el-select v-model="currentMenu.meta.icon" placeholder="请选择图标">
            <el-option
              v-for="icon in iconOptions"
              :key="icon"
              :value="icon"
              :label="icon"
            >
              <el-icon :size="16" style="margin-right: 8px">
                <component :is="icon" />
              </el-icon>
              <span>{{ icon }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="按钮权限">
          <el-select
            v-model="currentMenu.meta.butPermission"
            multiple
            placeholder="请选择权限"
            style="width: 100%"
          >
            <el-option
              v-for="perm in permissionOptions"
              :key="perm"
              :label="perm"
              :value="perm"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="是否隐藏">
          <el-switch v-model="currentMenu.meta.isHide" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import menuDataRaw from '@/api/modules/menuData'

interface MenuMeta {
  title: string
  icon?: string
  butPermission?: string[]
  isHide?: boolean
  isKeepAlive?: boolean
  isLink?: string
  isFull?: boolean
  isAffix?: boolean
}

interface MenuItem {
  path: string
  name: string
  component?: string
  redirect?: string
  meta: MenuMeta
  children?: MenuItem[]
  parentPath?: string // 用于跟踪父节点
}

// 图标选项
const iconOptions = [
  'HomeFilled',
  'List',
  'Lock',
  'Tools',
  'User',
  'Grid',
  'Menu',
  'DataLine',
  'SetUp',
  'Operation'
]

// 权限选项
const permissionOptions = ['add', 'delete', 'edit', 'view', 'export', 'import']

// 处理原始数据
const processedMenuData = ref<MenuItem[]>([])
const initMenuData = () => {
  const processChildren = (items: any[], parentPath?: string): MenuItem[] => {
    return items.map(item => ({
      ...item,
      parentPath: parentPath,
      children: item.children ? processChildren(item.children, item.path) : undefined
    }))
  }
  processedMenuData.value = processChildren(menuDataRaw.data)
}

// 对话框状态
const dialogVisible = ref(false)
const dialogTitle = ref('')
const currentMenu = reactive<MenuItem>({
  path: '',
  name: '',
  meta: {
    title: '',
    icon: '',
    butPermission: [],
    isHide: false
  }
})
const formRef = ref<FormInstance>()

// 表单验证规则
const formRules: FormRules = {
  'meta.title': [
    { required: true, message: '菜单名称不能为空', trigger: 'blur' },
    { min: 2, max: 20, message: '长度在2到20个字符', trigger: 'blur' }
  ],
  path: [
    { required: true, message: '路由路径不能为空', trigger: 'blur' },
    {
      pattern: /^\/[a-zA-Z0-9/-]+$/,
      message: '路径格式不正确，应以/开头',
      trigger: 'blur'
    }
  ]
}

// 添加根菜单
const handleAddRoot = () => {
  dialogTitle.value = '添加根菜单'
  Object.assign(currentMenu, {
    path: '',
    name: '',
    component: '',
    meta: {
      title: '',
      icon: '',
      butPermission: [],
      isHide: false
    }
  })
  dialogVisible.value = true
}

// 添加子菜单
const handleAddChild = (parent: MenuItem) => {
  dialogTitle.value = '添加子菜单'
  Object.assign(currentMenu, {
    path: '',
    name: '',
    component: '',
    meta: {
      title: '',
      icon: '',
      butPermission: [],
      isHide: false
    },
    parentPath: parent.path
  })
  dialogVisible.value = true
}

// 编辑菜单
const handleEdit = (row: MenuItem) => {
  dialogTitle.value = '编辑菜单'
  Object.assign(currentMenu, JSON.parse(JSON.stringify(row)))
  dialogVisible.value = true
}

// 删除菜单
const handleDelete = (target: MenuItem) => {
  const deleteNode = (data: MenuItem[]): boolean => {
    return data.some((item, index) => {
      if (item.path === target.path) {
        data.splice(index, 1)
        return true
      }
      if (item.children && deleteNode(item.children)) {
        return true
      }
      return false
    })
  }
  deleteNode(processedMenuData.value)
}

// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validate()
    
    const newItem = JSON.parse(JSON.stringify(currentMenu))
    delete newItem.parentPath

    if (dialogTitle.value.includes('添加')) {
      if (currentMenu.parentPath) {
        const parent = findMenuByPath(processedMenuData.value, currentMenu.parentPath)
        if (parent) {
          parent.children = parent.children || []
          parent.children.push(newItem)
        }
      } else {
        processedMenuData.value.push(newItem)
      }
    } else {
      updateMenu(processedMenuData.value, newItem)
    }
    
    dialogVisible.value = false
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}

// 递归查找菜单
const findMenuByPath = (data: MenuItem[], path: string): MenuItem | undefined => {
  for (const item of data) {
    if (item.path === path) return item
    if (item.children) {
      const found = findMenuByPath(item.children, path)
      if (found) return found
    }
  }
}

// 递归更新菜单
const updateMenu = (data: MenuItem[], target: MenuItem): boolean => {
  return data.some((item, index) => {
    if (item.path === target.path) {
      data[index] = { ...item, ...target }
      return true
    }
    if (item.children && updateMenu(item.children, target)) {
      return true
    }
    return false
  })
}

onMounted(() => {
  initMenuData()
})
</script>

<style scoped>
.menu-management-container {
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.1);
}

.header {
  margin-bottom: 20px;
}

.perm-tag {
  margin: 2px;
}
</style>